﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Windows.Forms;
using Facebook;

namespace FeedBack.UI {
    public partial class Form1 : Form {

        bool closed = false;
        FacebookClient fb;

        public Form1() {
            InitializeComponent();
            dtpStartDate.Value = DateTime.Today.AddDays(-1);
        }

        private void button1_Click(object sender, EventArgs e) {
            Start();
        }

        private void Start1() {
            webView.Visible = true;
            webView.Url = new Uri(string.Format("https://www.facebook.com/dialog/oauth?client_id={0}&redirect_uri=https%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_success.html&scope=read_stream&type=user_agent&display=popup",
                                            ConfigurationManager.AppSettings["AppId"]));
            Timer t = new Timer();
            t.Interval = 1000;
            t.Tick += (a, b) => {
                Debug.WriteLine(webView.Url);
                if (webView.Url.ToString().Contains("access_token")) {
                    t.Stop();
                    txtStory.Text = "";
                    webView.Visible = false;
                    txtStory.Visible = true;

                    var url = webView.Url.ToString(); ;
                    var start = url.IndexOf("access_token=") + "access_token=".Length;
                    var end = url.IndexOf("&", start);
                    var accessToken = url.Substring(start, end - start);

                    ProcessFeed(accessToken);
                }
            };
            t.Start();
        }

        private void Start() {

            var accessToken = txtToken.Text;
            if (chkResume.Checked && !string.IsNullOrWhiteSpace(txtInitPath.Text)) {
                fb = new FacebookClient();
                var processor = Setup(fb);
                fb.AccessToken = accessToken;
                
                new System.Threading.Thread(() => processor.Process(txtInitPath.Text, (int) numInit.Value)).Start();
            }
            else {
                if (string.IsNullOrWhiteSpace(txtToken.Text)) {
                    MessageBox.Show("Token needed");
                    return;
                }

                ProcessFeed(accessToken);
            }
        }

        private void ProcessFeed(string accessToken) {
            fb = new FacebookClient();
            fb.AccessToken = accessToken;

            var processor = Setup(fb);
            new System.Threading.Thread(() => processor.Process()).Start();
        }

        private FeedProcessor Setup(FacebookClient fb) {

            fb.HttpWebRequestFactory = url => {
                var request = new HttpWebRequestWrapper((HttpWebRequest)WebRequest.Create(url));
                request.ReadWriteTimeout = 10000;
                return request;
            };

            FeedProcessor processor = new FeedProcessor(fb, dtpStartDate.Value.Date.ToUniversalTime());
            processor.StoryProcessed += (s, e) => {
                if (!closed) {
                    this.Invoke(new Action(() => {
                        txtStory.Text = string.Format("{0}\r\n{1}\r\nCreated: {2}\r\nUpdated: {3}\r\n\r\n{4}\r\n{5}\r\n{6}",
                            e.Story.Get("from").Get<string>("name"),
                            e.Story.Get<string>("type"),
                            e.Story.Get<string>("created_time"),
                            e.Story.Get<string>("updated_time"),
                            e.Story.Get<string>("caption"),
                            e.Story.Get<string>("message"),
                            e.Story.Get<string>("description"),
                            e.Story.Get<string>("story")
                        );
                    }));
                }
            };

            processor.VideoInProgressUpdated += (s, e) => {
                if (!closed) {
                    this.Invoke(new Action(() => lblDownloadStatus.Text = string.Format("Download in progress: {0}", e.Count)));
                }
            };

            processor.Completed += (s, e) => {
                if (!closed) {
                    this.Invoke(new Action(() => {
                        MessageBox.Show(processor.CompleteStatus);
                        btnStart.Enabled = true;
                    }));
                }
            };

            btnStart.Enabled = false;
            return processor;
        }

        private void btnBrowse_Click(object sender, EventArgs e) {
            OpenFileDialog dialog = new OpenFileDialog();
            var result = dialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK) {
                var accessToken = txtToken.Text;
                fb = new FacebookClient();
                var processor = Setup(fb);
                fb.AccessToken = accessToken;

                var dir = Path.GetDirectoryName(dialog.FileName);
                System.Threading.ThreadPool.QueueUserWorkItem((x) => processor.ProcessFileFeed(Directory.GetFiles(dir, "*.json")));
            }
        }

        private void chkLink_CheckedChanged(object sender, EventArgs e) {
            FeedBack.Configuration.DownloadLink = chkLink.Checked;
        }

        private void chkPhoto_CheckedChanged(object sender, EventArgs e) {
            FeedBack.Configuration.DownloadPhoto = chkPhoto.Checked;
        }

        private void chkVideo_CheckedChanged(object sender, EventArgs e) {
            FeedBack.Configuration.DownloadVideo = chkVideo.Checked;
        }

        private void chkOverwrite_CheckedChanged(object sender, EventArgs e) {
            FeedBack.Configuration.Overwrite = chkOverwrite.Checked;
        }

        private void chkResume_CheckedChanged(object sender, EventArgs e) {
            txtInitPath.Enabled = chkResume.Checked;
            numInit.Enabled = chkResume.Checked;
        }

        private void chkStatus_CheckedChanged(object sender, EventArgs e) {
            FeedBack.Configuration.DownloadStatus = chkStatus.Checked;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
            closed = true;
        }

        private void numLimit_ValueChanged(object sender, EventArgs e) {
            FeedBack.Configuration.Limit = (int) numLimit.Value;
        }

        private void btnFeedList_Click(object sender, EventArgs e) {
            if (string.IsNullOrWhiteSpace(txtToken.Text)) {
                MessageBox.Show("Token needed");
                return;
            }

            OpenFileDialog dialog = new OpenFileDialog();
            var result = dialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK) {
                var accessToken = txtToken.Text;
                fb = new FacebookClient();
                var processor = Setup(fb);
                fb.AccessToken = accessToken;

                System.Threading.ThreadPool.QueueUserWorkItem((x) => processor.ProcessUsers(File.ReadLines(dialog.FileName)));
                
            }
        }

        private void btnToSQL_Click(object sender, EventArgs e) {
            if (string.IsNullOrWhiteSpace(Configuration.Token)) {
                MessageBox.Show("Token needed");
                return;
            }

            OpenFileDialog dialog = new OpenFileDialog();
            var result = dialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK) {
                fb = new FacebookClient();
                var processor = Setup(fb);
                fb.AccessToken = Configuration.Token;

                var dir = Path.GetDirectoryName(dialog.FileName);
                FileStoryParser parser = new FileStoryParser(Directory.GetFiles(dir, "*.json", SearchOption.AllDirectories),  fb.DeserializeJson);
                SqlImporter importer = new SqlImporter(fb);

                System.Threading.ThreadPool.QueueUserWorkItem((x) => {
                    var stories = parser.GetStories();
                    try {
                        importer.Import(stories);
                        if (!closed) {
                            this.Invoke(new Action(() => MessageBox.Show("Import completed")));
                        }
                        
                    }
                    catch (Exception ex) {
                        if (!closed) {
                            this.Invoke(new Action(() => MessageBox.Show(ex.Message)));
                        }
                    }
                });
            }
        }

        private void txtToken_TextChanged(object sender, EventArgs e) {
            if (fb != null) {
                fb.AccessToken = txtToken.Text;
            }
        }

        private void chkPagePostOnly_CheckedChanged(object sender, EventArgs e) {
            Configuration.SavePagePostOnly = chkPagePostOnly.Checked;
        }
    }
}
